using System.Collections.Generic;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using NGen;

namespace AeonOfStrife.Misc
{
	public interface IPathfindingObject
	{
		void FindPath();
	}

	public class PathfindingData
	{
		public Vector2 ScreenSize { get; protected set; }

		public Vector2 CellSize { get; protected set; }

		public float[,] CellCostMultiplier { get; set; }

		public bool[,] CellPassableMap { get; set; }

		public Point WorldSize { get; set; }

		public Point GridSize { get; protected set; }

		public HashSet<IPathfindingObject> m_pathfindingQueue = new HashSet<IPathfindingObject>();

		private SpriteFont m_font;

		public PathfindingData(Point p_gridSize, Point p_worldSize) {
			GridSize = p_gridSize;
			WorldSize = p_worldSize;
			CellCostMultiplier = new float[GridSize.X,GridSize.Y];
			CellPassableMap = new bool[GridSize.X,GridSize.Y];
			CellSize = new Vector2((float) WorldSize.X / (float) GridSize.X, (float) WorldSize.Y / (float) GridSize.Y);
			ScreenSize = new Vector2(GameEngine.GameWindow.ClientBounds.Width, GameEngine.GameWindow.ClientBounds.Height);
			m_font = GameEngine.GameContent.Load<SpriteFont>("Content\\font");
		}

		public Point ConvertScreenToCellCoord(Vector2 p_position) {
			return new Point((int) (p_position.X / CellSize.X), (int) (p_position.Y / CellSize.Y));
		}

		public Vector2 ConvertCellCoordToScreenCoord(Point p_cell) {
			return new Vector2((p_cell.X * CellSize.X), (p_cell.Y * CellSize.Y));
		}

		public void IncrementMultiplier(int p_x, int p_y) {
			CellCostMultiplier[p_x, p_y] += Constants.c_PATHFINDING_INCREMENT_AMOUNT/2f;

			for(int i = -1; i < 2; i++) {
				for(int j = -1; j < 2; j++) {
					CellCostMultiplier[p_x+i, p_y+j] += Constants.c_PATHFINDING_INCREMENT_AMOUNT/2f;
				}
			}
		}

		public void DecrementMultiplier(int p_x, int p_y) {
			CellCostMultiplier[p_x, p_y] -= Constants.c_PATHFINDING_INCREMENT_AMOUNT/2f;

			for(int i = -1; i < 2; i++) {
				for(int j = -1; j < 2; j++) {
					CellCostMultiplier[p_x + i, p_y + j] -= Constants.c_PATHFINDING_INCREMENT_AMOUNT / 2f;
					if(CellCostMultiplier[p_x+i, p_y+j] < 1)
						CellCostMultiplier[p_x+i, p_y+j] = 1;
				}
			}
			
		}

		public void DrawDebug() {
			for(var x = 0; x < WorldSize.X; x++) {
				for(var y = 0; y < WorldSize.Y; y++) {
					var pos = ConvertCellCoordToScreenCoord(new Point(x, y));
					GameEngine.SpriteBatch.DrawString(
						m_font,
						CellCostMultiplier[x, y].ToString(),
						pos,
						!CellPassableMap[x, y] ? Color.Yellow : Color.Red,
						0,
						Vector2.Zero,
						1,
						SpriteEffects.None,
						0.99f);
				}
			}
		}

		public void Enqueue(IPathfindingObject p_object) {
			m_pathfindingQueue.Add(p_object);
		}

		public void Dequeue(IPathfindingObject p_object) {
			m_pathfindingQueue.Remove(p_object);

		}

		public void ProcessQueue() {
			if(m_pathfindingQueue.Count == 0) {
				return;
			}

			var itr = m_pathfindingQueue.GetEnumerator();
			itr.MoveNext();
			var pathObj = itr.Current;
			m_pathfindingQueue.Remove(pathObj);

			pathObj.FindPath();
			 
		}
	}
}